<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <!-- 修改标题文字，直接将 💗 Love you 💗 改成你想要的即可 -->
  <title>💗 Love you 💗</title>
  <style type="text/css">
    body {
      margin: 0;
      overflow: hidden;
      background: #333;
      background-image: url('https://img2.baidu.com/it/u=398382634,3682990943&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500');
      background-size: cover;
    }

    canvas {
      position: absolute;
      width: 100%;
      height: 100%;
    }

    /* #pinkboard, */
    .heart {
      animation: anim 1.5s ease-in-out infinite;
      -webkit-animation: anim 1.5s ease-in-out infinite;
      -o-animation: anim 1.5s ease-in-out infinite;
      -moz-animation: anim 1.5s ease-in-out infinite;
    }

    @keyframes anim {
      0% {
        transform: scale(0.8);
      }

      25% {
        transform: scale(0.7);
      }

      50% {
        transform: scale(1);
      }

      75% {
        transform: scale(0.7);
      }

      100% {
        transform: scale(0.8);
      }
    }

    @-webkit-keyframes anim {
      0% {
        -webkit-transform: scale(0.8);
      }

      /* 25% {
        -webkit-transform: scale(0.7);
      } */

      50% {
        -webkit-transform: scale(1);
      }

      /* 75% {
        -webkit-transform: scale(0.7);
      } */

      100% {
        -webkit-transform: scale(0.8);
      }
    }

    @-o-keyframes anim {
      0% {
        -o-transform: scale(0.8);
      }

      25% {
        -o-transform: scale(0.7);
      }

      50% {
        -o-transform: scale(1);
      }

      75% {
        -o-transform: scale(0.7);
      }

      100% {
        -o-transform: scale(0.8);
      }
    }

    @-moz-keyframes anim {
      0% {
        -moz-transform: scale(0.8);
      }

      25% {
        -moz-transform: scale(0.7);
      }

      50% {
        -moz-transform: scale(1);
      }

      75% {
        -moz-transform: scale(0.7);
      }

      100% {
        -moz-transform: scale(0.8);
      }
    }

    #name {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      margin-top: -20px;
      font-size: 46px;
      color: #eea2a4;
    }

    .type_words {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 180px;
      height: 180px;
      color: #f1dadb;
      padding: 20px;
      text-transform: lowercase;
    }
  </style>
</head>

<body>
  <canvas id="pinkboard" width="1707" height="868"></canvas>
  <canvas id="heart" width="1000" height="600"></canvas>
  <canvas id="canvas" width="1707" height="868"></canvas>
  <audio id="audioDom" src="https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7170534431801838367.mp3" preload="auto"
     loop="loop"></audio>
  <div class="type_words" id="contents"></div>
  <a href="https://mp.weixin.qq.com/s?__biz=MzA5Njg2OTA0NA==&mid=2247483863&idx=1&sn=31592da349b2ae1a9b652128a657816d&chksm=90a8ce0ca7df471a85250287f0460b3da6793c7484fa905f77d2a21433adfd8f9e610dd9058f#rd" class="hide_buttom"
    style="position: fixed;top: 4%;right: 10px;width: 35px;height: 35px;z-index: 999;background: #696969;border-radius: 50%;padding: 1.0px;text-align: center;color: #ddd;text-decoration: none;   clear: both; line-height: 35px; 	margin:auto;   font-size: 13px;   ">制作</a>

  <a href="https://mp.weixin.qq.com/s?__biz=MzA5Njg2OTA0NA==&mid=2247483825&idx=1&sn=61be360bb6eaa516113599812c6d0aca&chksm=90a8ce6aa7df477cbf8b3871c92c61878c4d40c5278ec9836ad77a07891dcbb051a58772e85e#rd" class="hide_buttom"
    style="position: fixed;top: 10%;right: 10px;width: 35px;height: 35px;z-index: 999;background: #696969;border-radius: 50%;padding: 1.0px;text-align: center;color: #ddd;text-decoration: none;   clear: both; line-height: 35px; 	margin:auto;   font-size: 13px;   ">更多</a>
  <script>
      function musicInBrowserHandler() {
      var media = document.querySelector('#audioDom');
      media.play(); 
    }
    document.body.addEventListener('click', musicInBrowserHandler);
    function fillText() {
      const colorss = [
        "#eea2a4",
        "#8fb7d3",
        "#b7d4c6",
        "#c3bedd",
        "#f1d5e4",
        "#cae1d3",
        "#f3c89d",
        "#d0b0c3",
        "#819d53",
        "#c99294",
        "#cec884",
        "#ff8e70",
        "#e0a111",
        "#fffdf6",
        "#cbd7ac",
        "#e8c6c0",
        "#dc9898",
        "#5d3f51",
        "#61649f",
        "#0f59a4"
      ]; //用来设置的颜色
      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
      let count = 1;

      var ww = window.innerWidth;
      var wh = window.innerHeight;

      var hearts = [];

      function init() {
        requestAnimationFrame(render);
        canvas.width = ww;
        canvas.height = wh;
        for (var i = 0; i < 100; i++) {
          hearts.push(new Heart());
        }
      }

      function Heart() {
        this.x = Math.random() * ww;
        this.y = Math.random() * wh;
        this.opacity = Math.random() * 0.5 + 0.5;
        this.vel = {
          x: (Math.random() - 0.5) * 4,
          y: (Math.random() - 0.5) * 4,
        };
        this.targetScale = Math.random() * 0.15 + 0.02;
        this.scale = this.targetScale * Math.random();
      }

      Heart.prototype.update = function (i) {
        this.x += this.vel.x;
        this.y += this.vel.y;

        this.scale += (this.targetScale - this.scale) * 0.01;
        if (this.x - this.width > ww || this.x + this.width < 0) {
          this.scale = 0;
          this.x = Math.random() * ww;
        }
        if (this.y - this.height > wh || this.y + this.height < 0) {
          this.scale = 0;
          this.y = Math.random() * wh;
        }
        this.width = 473.8;
        this.height = 408.6;
      };
      Heart.prototype.draw = function (i, text) {
        ctx.globalAlpha = this.opacity;
        ctx.font = `${180 * this.scale}px "微软雅黑"`;
        // ctx.font="20px";
        ctx.fillStyle = colorss[i % 18];
        ctx.fillText(
          text,
          this.x - this.width * 0.5,
          this.y - this.height * 0.5,
          this.width,
          this.height
        );
      };

      function getUrlName() {
        const getParameters = url => JSON.parse(`{"${decodeURI(url.split("?")?.[1])?.replace(/"/g, '\\"')?.replace(/&/g, '","')?.replace(/=/g, '":"')}"}`
        )
        const url = window.location.href;
        if (url.indexOf('name=') > -1) {
          const obj = getParameters(url);
          return obj.name;
        }
        return "";
      }

      function render() {
        ctx.clearRect(0, 0, ww, wh);
        // 修改文字 想要多几个飘着的文字
        var text = ['love you', '1314', "520"];
        var name = getUrlName();
        for (var i = 0; i < 100; i++) {
          hearts[i].update(i);
          hearts[i].draw(i, name || text[i % text.length]);
        }
        requestAnimationFrame(render);
      }
      init();

      window.addEventListener("resize", function () {
        ww = window.innerWidth;
        wh = window.innerHeight;
      });
    }
    function heartBeat() {
      /*
       * Settings
       */
      var settings = {
        particles: {
          length: 500, // maximum amount of particles
          duration: 2, // particle duration in sec
          velocity: 100, // particle velocity in pixels/sec
          effect: -0.75, // play with this for a nice effect
          size: 30, // particle size in pixels
        },
      };

      /*
       * RequestAnimationFrame polyfill by Erik M?ller
       */
      (function () {
        var b = 0;
        var c = ["ms", "moz", "webkit", "o"];
        for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) {
          window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"];
          window.cancelAnimationFrame =
            window[c[a] + "CancelAnimationFrame"] ||
            window[c[a] + "CancelRequestAnimationFrame"];
        }
        if (!window.requestAnimationFrame) {
          window.requestAnimationFrame = function (h, e) {
            var d = new Date().getTime();
            var f = Math.max(0, 16 - (d - b));
            var g = window.setTimeout(function () {
              h(d + f);
            }, f);
            b = d + f;
            return g;
          };
        }
        if (!window.cancelAnimationFrame) {
          window.cancelAnimationFrame = function (d) {
            clearTimeout(d);
          };
        }
      })();

      /*
       * Point class
       */
      var Point = (function () {
        function Point(x, y) {
          this.x = typeof x !== "undefined" ? x : 0;
          this.y = typeof y !== "undefined" ? y : 0;
        }
        Point.prototype.clone = function () {
          return new Point(this.x, this.y);
        };
        Point.prototype.length = function (length) {
          if (typeof length == "undefined")
            return Math.sqrt(this.x * this.x + this.y * this.y);
          this.normalize();
          this.x *= length;
          this.y *= length;
          return this;
        };
        Point.prototype.normalize = function () {
          var length = this.length();
          this.x /= length;
          this.y /= length;
          return this;
        };
        return Point;
      })();

      /*
       * Particle class
       */

      var Particle = (function () {
        function Particle() {
          this.position = new Point();
          this.velocity = new Point();
          this.acceleration = new Point();
          this.age = 0;
        }
        Particle.prototype.initialize = function (x, y, dx, dy) {
          this.position.x = x;
          this.position.y = y;
          this.velocity.x = dx;
          this.velocity.y = dy;
          this.acceleration.x = dx * settings.particles.effect;
          this.acceleration.y = dy * settings.particles.effect;
          this.age = 0;
        };
        Particle.prototype.update = function (deltaTime) {
          this.position.x += this.velocity.x * deltaTime;
          this.position.y += this.velocity.y * deltaTime;
          this.velocity.x += this.acceleration.x * deltaTime;
          this.velocity.y += this.acceleration.y * deltaTime;
          this.age += deltaTime;
        };
        Particle.prototype.draw = function (context, image) {
          function ease(t) {
            return --t * t * t + 1;
          }
          var size = image.width * ease(this.age / settings.particles.duration);
          context.globalAlpha = 1 - this.age / settings.particles.duration;
          context.drawImage(
            image,
            this.position.x - size / 2,
            this.position.y - size / 2,
            size,
            size
          );
        };
        return Particle;
      })();

      /*
       * ParticlePool class
       */
      var ParticlePool = (function () {
        var particles,
          firstActive = 0,
          firstFree = 0,
          duration = settings.particles.duration;

        function ParticlePool(length) {
          // create and populate particle pool
          particles = new Array(length);
          for (var i = 0; i < particles.length; i++)
            particles[i] = new Particle();
        }
        ParticlePool.prototype.add = function (x, y, dx, dy) {
          particles[firstFree].initialize(x, y, dx, dy);

          // handle circular queue
          firstFree++;
          if (firstFree == particles.length) firstFree = 0;
          if (firstActive == firstFree) firstActive++;
          if (firstActive == particles.length) firstActive = 0;
        };
        ParticlePool.prototype.update = function (deltaTime) {
          var i;

          // update active particles
          if (firstActive < firstFree) {
            for (i = firstActive; i < firstFree; i++)
              particles[i].update(deltaTime);
          }
          if (firstFree < firstActive) {
            for (i = firstActive; i < particles.length; i++)
              particles[i].update(deltaTime);
            for (i = 0; i < firstFree; i++) particles[i].update(deltaTime);
          }

          // remove inactive particles
          while (
            particles[firstActive].age >= duration &&
            firstActive != firstFree
          ) {
            firstActive++;
            if (firstActive == particles.length) firstActive = 0;
          }
        };
        ParticlePool.prototype.draw = function (context, image) {
          // draw active particles
          if (firstActive < firstFree) {
            for (i = firstActive; i < firstFree; i++)
              particles[i].draw(context, image);
          }
          if (firstFree < firstActive) {
            for (i = firstActive; i < particles.length; i++)
              particles[i].draw(context, image);
            for (i = 0; i < firstFree; i++) particles[i].draw(context, image);
          }
        };
        return ParticlePool;
      })();

      /*
       * Putting it all together
       */
      (function (canvas) {
        var context = canvas.getContext("2d"),
          particles = new ParticlePool(settings.particles.length),
          particleRate =
            settings.particles.length / settings.particles.duration, // particles/sec
          time;

        // get point on heart with -PI <= t <= PI
        function pointOnHeart(t) {
          return new Point(
            160 * Math.pow(Math.sin(t), 3),
            130 * Math.cos(t) -
            50 * Math.cos(2 * t) -
            20 * Math.cos(3 * t) -
            10 * Math.cos(4 * t) +
            25
          );
        }

        // creating the particle image using a dummy canvas
        var image = (function () {
          var canvas = document.createElement("canvas"),
            context = canvas.getContext("2d");
          canvas.width = settings.particles.size;
          canvas.height = settings.particles.size;
          // helper function to create the path
          function to(t) {
            var point = pointOnHeart(t);
            point.x =
              settings.particles.size / 2 +
              (point.x * settings.particles.size) / 350;
            point.y =
              settings.particles.size / 2 -
              (point.y * settings.particles.size) / 350;
            return point;
          }
          // create the path
          context.beginPath();
          var t = -Math.PI;
          var point = to(t);
          context.moveTo(point.x, point.y);
          while (t < Math.PI) {
            t += 0.01; // baby steps!
            point = to(t);
            context.lineTo(point.x, point.y);
          }
          context.closePath();
          // 修改爱心颜色
          context.fillStyle = "#eea2a4";
          context.fill();
          // create the image
          var image = new Image();
          image.src = canvas.toDataURL();
          return image;
        })();

        // render that thing!
        function render() {
          // next animation frame
          requestAnimationFrame(render);

          // update time
          var newTime = new Date().getTime() / 1000,
            deltaTime = newTime - (time || newTime);
          time = newTime;

          // clear canvas
          context.clearRect(0, 0, canvas.width, canvas.height);

          // create new particles
          var amount = particleRate * deltaTime;
          for (var i = 0; i < amount; i++) {
            var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
            var dir = pos.clone().length(settings.particles.velocity);
            particles.add(
              canvas.width / 2 + pos.x,
              canvas.height / 2 - pos.y,
              dir.x,
              -dir.y
            );
          }

          // update and draw particles
          particles.update(deltaTime);
          particles.draw(context, image);
        }

        // handle (re-)sizing of the canvas
        function onResize() {
          canvas.width = canvas.clientWidth;
          canvas.height = canvas.clientHeight;
        }
        window.onresize = onResize;

        // delay rendering bootstrap
        setTimeout(function () {
          onResize();
          render();
        }, 10);
      })(document.getElementById("pinkboard"));
    }
    function lineHeartAni() {
      var heart = document.getElementById('heart');
      var ctx = heart.getContext('2d');
      var radian_cal = 0;
      var radian_add = Math.PI / 180;
      var x, y;
      ctx.beginPath();

      ctx.shadowBlur = 3;
      ctx.shadowColor = "#eea2a4";
      ctx.strokeStyle = "#eea2a4";

      ctx.translate(500, 300);

      ctx.moveTo(calX(radian_cal), calY(radian_cal));

      function draw() {
        if (radian_cal <= 2 * Math.PI) {
          radian_cal += radian_add;
          x = calX(radian_cal);
          y = calY(radian_cal);
          ctx.lineTo(x, y);
          ctx.stroke();
        } else {
          clearInterval(time);
          ctx.fillStyle = "#eea2a4";
          ctx.fill();
          fillText();
          heartBeat();
          var heartAni = document.getElementById('heart');
          heartAni.classList.add('heart')
        }
      }
      var scaleSize = 8;
      var xscaleSize = 16;
      if (navigator.userAgent.includes('Mobile')) {
        scaleSize = 2;
        xscaleSize = 48;
      }

      function calX(p) {
        return scaleSize * xscaleSize * Math.pow(Math.sin(p), 3);
      }

      function calY(q) {
        return -scaleSize * (13 * Math.cos(q) - 5 * Math.cos(2 * q) - 2 * Math.cos(3 * q) - Math.cos(4 * q));
      }
      var time = setInterval(draw, 10);
    }
    fillText();
    heartBeat();

    // 动画线条画爱心方法
    // 画完才出现文字 和满屏爱心
    // lineHeartAni();
  </script>
  <script>
    function start() {
      // 修改爱心里面的文案：直接修改下方文字即可
      const text = [
        "于我而言，你是最好且是唯一❤️",
        "宝贝，永远爱你❤️"
      ]
      let str = text.join('<br><br>')
      let str_ = ''
      let i = 0
      let content = document.getElementById('contents')
      let timer = setInterval(() => {
        if (str_.length < str.length) {
          str_ += str[i++]
          content.innerHTML = '<p>' + str_ + '<span class="xx" style="opacity: 1;    color: red;">❤</span></p>'                        //打印时加光标
        } else {
          clearInterval(timer)
          content.innerHTML = '<p>' + str_ + '</p>'
        }
      }, 100)
    }
    setTimeout(() => {
      start();
    }, 1000);
  </script>
</body>

</html>
